package com.manda.smart.hub.common.strategy;

import com.manda.smart.hub.common.comparator.Sortable;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;

/**
 * 策略工厂
 * 负责组装和执行策略
 *
 * @author hongda.li
 */
public record StrategyFactory<Context>(List<Strategy<Context>> strategyList) implements Sortable<Strategy<Context>> {

    /**
     * 针对给定的策略排序器，将所有策略实现进行排序
     *
     * @param comparator 自定义策略排序器
     */
    @Override
    public void sort(Comparator<Strategy<Context>> comparator) {
        Objects.requireNonNull(comparator);
        this.strategyList.sort(comparator);
    }

    /**
     * 执行第一个符合的策略
     *
     * @param context 上下文
     */
    public void applyFirst(Context context) {
        this.applyFirst(context, null);
    }

    /**
     * 执行第一个符合的策略
     * 若有策略均不支持时，则执行兜底策略
     *
     * @param context         上下文
     * @param defaultStrategy 当所有策略均不支持时的默认兜底策略
     */
    public void applyFirst(Context context, Strategy<Context> defaultStrategy) {
        for (Strategy<Context> strategy : this.strategyList) {
            if (strategy.isMatch(context)) {
                strategy.ifMatch(context);
                return;
            } else {
                strategy.elseNoneMatch(context);
            }
        }

        if (defaultStrategy != null) {
            defaultStrategy.ifMatch(context);
        }
    }

    /**
     * 执行所有符合的策略
     *
     * @param context 上下文
     */
    public void applyAll(Context context) {
        this.strategyList.forEach(strategy -> strategy.applyStrategy(context));
    }
}
